#include "../../src/util/os_util.hh"
#include "../../src/util/string_util.hh"
#include "../framework/unittest.hh"
#include <fstream>

FIXTURE_BEGIN(test_util)

using namespace kratos;

CASE(TestMkdir1) {
  ASSERT_TRUE(util::make_dir("test_dir"));
  util::rm_empty_dir("test_dir");
}

CASE(TestGetHostIp1) {
  ASSERT_TRUE(util::get_host_ip("localhost") == "127.0.0.1");
  ASSERT_TRUE(util::get_host_ip("www.baidu.com").size() > 0);
}

CASE(TestGetBinaryPath1) {
  auto path = util::get_binary_path();
  ASSERT_TRUE(path.size() > 0);
}

CASE(TestGetBinaryName1) {
  auto path = util::get_binary_name();
  ASSERT_TRUE(path.find("unittest") != std::string::npos);
}

CASE(TestEndWith) {
  ASSERT_TRUE(util::endWith("abc123", "123"));
  ASSERT_TRUE(util::endWith("abc123", "23"));
  ASSERT_TRUE(util::endWith("abc123", "3"));
  ASSERT_FALSE(util::endWith("abc123", "12"));
  ASSERT_FALSE(util::endWith("abc123", "1"));
  ASSERT_FALSE(util::endWith("abc123", "a"));
  ASSERT_FALSE(util::endWith("abc123", "ab"));
  ASSERT_FALSE(util::endWith("abc123", "abc"));
  ASSERT_FALSE(util::endWith("abc123", "b"));
  ASSERT_FALSE(util::endWith("abc123", "c"));
  ASSERT_FALSE(util::endWith("", ""));
  ASSERT_FALSE(util::endWith("", "aaa"));
  ASSERT_FALSE(util::endWith("bbb", ""));
}

CASE(TestStartWith) {
  ASSERT_TRUE(util::startWith("abc123", "abc"));
  ASSERT_TRUE(util::startWith("abc123", "ab"));
  ASSERT_TRUE(util::startWith("abc123", "a"));
  ASSERT_FALSE(util::startWith("abc123", "b"));
  ASSERT_FALSE(util::startWith("abc123", "c"));
  ASSERT_FALSE(util::startWith("abc123", "123"));
  ASSERT_FALSE(util::startWith("", ""));
  ASSERT_FALSE(util::startWith("", "aa"));
  ASSERT_FALSE(util::startWith("aa", ""));
}

CASE(TestRemove) {
  ASSERT_TRUE("123" == util::remove("abc123", "abc"));
  ASSERT_TRUE("abc" == util::remove("abc123", "123"));
  ASSERT_TRUE("a123" == util::remove("abc123", "bc"));
  ASSERT_TRUE("abc123" == util::remove("abc123", ""));
}

CASE(TestTrim) {
  ASSERT_TRUE("abc123" == util::trim("   abc123"));
  ASSERT_TRUE("abc123" == util::trim("\t abc123 \t", " \t"));
  ASSERT_TRUE("abc123 " == util::ltrim("   abc123 "));
  ASSERT_TRUE(" abc123" == util::rtrim(" abc123  "));
  ASSERT_TRUE("" == util::trim(""));
  ASSERT_TRUE("" == util::ltrim(""));
  ASSERT_TRUE("" == util::rtrim(""));
}

CASE(TestGetFileName1) {
  ASSERT_TRUE("file" == util::get_file_name("\\a\\b\\c\\file.ext"));
  ASSERT_TRUE("file" == util::get_file_name("/a/b/c/file.ext"));
  ASSERT_TRUE("file" == util::get_file_name("\\a\\b\\c\\file"));
  ASSERT_TRUE("file" == util::get_file_name("/a/b/c/file"));
  ASSERT_TRUE(util::get_file_name("") == "");
}

CASE(TestReplace1) {
  ASSERT_TRUE("ab123ef" == util::replace("abcdef", "cd", "123"));
}

CASE(TestHasSubString1) { ASSERT_TRUE(util::has_sub_string("123456", "23")); }

CASE(TestIsDomainAddress1) {
  ASSERT_TRUE(util::is_domain_address("www.baidu.com"));
  ASSERT_TRUE(!util::is_domain_address("1.2.3.4"));
}

CASE(TestGetFileExt1){ASSERT_TRUE("ext" == util::get_file_ext("/a/b/c/a.ext"))}

CASE(TestGetFileInDirectory1) {
  std::fstream fs;
  fs.open("file.ext123", std::ios::out | std::ios::trunc);
  fs.close();
  std::vector<std::string> files;
  util::get_file_in_directory(".", "ext123", files);
  ASSERT_TRUE(files.size() == 1);
  ASSERT_TRUE(util::endWith(files[0], "file.ext123"));
  util::remove_file("file.ext123");
}

CASE(TestRenameFile1) {
  std::fstream fs;
  fs.open("file_name_1", std::ios::out | std::ios::trunc);
  fs.close();
  ASSERT_TRUE(util::rename_file("file_name_1", "file_name_2"));
  ASSERT_TRUE(!util::is_path_exists("file_name_1"));
  ASSERT_TRUE(util::is_path_exists("file_name_2"));
  util::remove_file("file_name_2");
}

CASE(TestSplit1) {
  std::vector<std::string> result;
  util::split("a:b:c", ":", result);
  ASSERT_TRUE(result.size() == 3);
  ASSERT_TRUE(result[0] == "a");
  ASSERT_TRUE(result[1] == "b");
  ASSERT_TRUE(result[2] == "c");
  util::split("", "", result);
  ASSERT_TRUE(result.empty());
  util::split("abc", "efg", result);
  ASSERT_TRUE(result.size() == 1 && (result[0] == "abc"));
  util::split(":", ":", result);
  ASSERT_TRUE(result.size() == 0);
  util::split("abc", "/", result);
  ASSERT_TRUE(result.size() == 1);
}

CASE(TestSplitOf1) {
  std::vector<std::string> result;
  util::splitOf("a,b:c", ",:", result);
  ASSERT_TRUE(result.size() == 3);
  ASSERT_TRUE(result[0] == "a");
  ASSERT_TRUE(result[1] == "b");
  ASSERT_TRUE(result[2] == "c");
  util::splitOf("", "", result);
  ASSERT_TRUE(result.empty());
  util::splitOf("abc", "efg", result);
  ASSERT_TRUE(result.empty());
  util::splitOf(",:", ",:", result);
  ASSERT_TRUE(result.size() == 0);
  util::splitOf("", "", result);
  ASSERT_TRUE(result.size() == 0);
}

CASE(TestSplitBy1) {
  std::vector<std::string> result;
  util::splitBy("a:b:c", ':', result);
  ASSERT_TRUE(result.size() == 3);
  ASSERT_TRUE(result[0] == "a:");
  ASSERT_TRUE(result[1] == "b:");
  ASSERT_TRUE(result[2] == "c");
  util::splitBy("", ':', result);
  ASSERT_TRUE(result.empty());
  util::splitBy("::", ':', result);
  ASSERT_TRUE(result.size() == 2);
  ASSERT_TRUE(result[0] == ":");
  ASSERT_TRUE(result[1] == ":");
}

CASE(Test_is_ip_address1) {
  ASSERT_TRUE(util::is_ip_address("1.2.3.4"));
  ASSERT_TRUE(!util::is_ip_address(""));
  ASSERT_TRUE(!util::is_ip_address("a.b.c"));
}

CASE(Test_isnumber1) {
  ASSERT_TRUE(util::isnumber("1235"));
  ASSERT_TRUE(!util::isnumber("abc"));
  ASSERT_TRUE(util::isnumber("1.2"));
  ASSERT_TRUE(util::isnumber("-12"));
  ASSERT_TRUE(util::isnumber("-1.2"));
}

CASE(Test_is_date_string_fmt1) {
  ASSERT_TRUE(util::is_date_string_fmt1("1900/01/01 01:01:01"));
  ASSERT_FALSE(util::is_date_string_fmt1("1900/1/1 01:01:01"));
}

CASE(Test_is_date_string_fmt2) {
  ASSERT_TRUE(util::is_date_string_fmt2("1900-01-01 01:01:01"));
  ASSERT_FALSE(util::is_date_string_fmt2("1900-1-1 01:01:01"));
}

CASE(Test_get_path1) {
  ASSERT_TRUE(util::get_path("a/b/c/file.ext") == "a/b/c");
  ASSERT_TRUE(util::get_path("a\\b\\c\\file.ext") == "a\\b\\c");
  ASSERT_TRUE(util::get_path("dddd") == "dddd");
}

CASE(Test_get_host_config1) {
  std::string s = "a:\\\\1.1.1.1:123";
  std::string type;
  std::string ip;
  std::int32_t port;
  util::get_host_config(s, ip, port, type);
  ASSERT_TRUE(ip == "1.1.1.1");
  ASSERT_TRUE(port == 123);
  ASSERT_TRUE(type == "a");
}

CASE(Test_get_host_config2) {
  std::string s = "a:\\\\";
  std::string type;
  std::string ip;
  std::int32_t port;
  ASSERT_TRUE(!util::get_host_config(s, ip, port, type));
}

CASE(Test_get_host_config3) {
  std::string s = "a:\\\\1.1.1.1";
  std::string type;
  std::string ip;
  std::int32_t port;
  ASSERT_TRUE(!util::get_host_config(s, ip, port, type));
}

CASE(Test_get_host_config4) {
  std::string s = ":\\\\1.1.1.1";
  std::string type;
  std::string ip;
  std::int32_t port;
  ASSERT_TRUE(!util::get_host_config(s, ip, port, type));
}

CASE(Test_get_host_config5) {
  std::string s = "tcp:\\\\1.1.1.1:123";
  std::string ip;
  std::int32_t port;
  ASSERT_TRUE(util::get_host_config(s, ip, port));
  ASSERT_TRUE(ip == "1.1.1.1");
  ASSERT_TRUE(port == 123);
}

FIXTURE_END(test_util)
